
#ifndef DEVIL1GEO_H
#define DEVIL1GEO_H
#include <stdint.h>
#include <stdbool.h>


#pragma pack(push, 1)
struct Header {
    unsigned char numMesh;
    unsigned char unknownNumberB;
    unsigned char unknownNumberC;
    unsigned char unknownNumberD;
    uint32_t padding;   // <format=hex>
    uint64_t unknownOffset;
};

struct MeshHeader {
    int16_t   numBatch;
    int16_t   numVertex;
    uint32_t  u;        // <format=hex>
    uint64_t  offsetBatches;
    uint64_t  flags;
}; // put these in an array of size: [header.numMesh]

struct Coordinate {
    float x, y, z;
};

struct UVs {
    int16_t u, v;
};

struct BoneIndexes {
    unsigned char indexes[4]; // from ubyte
};

struct BoneWeights {
    uint16_t weights; // <format=hex>
};

struct BatchData {
    int16_t   numVertex;
    int16_t   uB;
    uint32_t  padding;           // <format=hex>
    uint64_t  offsetPositions;   // <format=hex>
    uint64_t  offsetNormals;     // <format=hex>
    uint64_t  offsetUVs;         // <format=hex>
    uint64_t  offsetBoneIndexes; // <format=hex>
    uint64_t  offsetBoneWeights; // <format=hex>
    uint64_t  offsets[1];        // <format=hex>
};

struct VertexData {
    // following structs should in an array of size 'numVertex'
    struct Coordinate   *positions;
    struct Coordinate   *normals;
    struct UVs          *u;
    struct BoneIndexes  *bi;
    struct BoneWeights  *bw;
};

struct Batch {
    struct BatchData  *bd; // pointer to region in file data
    struct VertexData vd;  // collection of pointers to regions in file data
};

struct Mesh {
    // array of batches
    struct Batch *b;
};

#pragma pack(pop)

typedef struct { 
// input: pointer to struct
    void (* const printheader)    (struct Header*);

// input: pointer to struct
    void (* const printmeshheader)(struct MeshHeader*);

// input: pointer to struct
    void (* const printbatch)     (struct Batch*);

// input: pointer to struct
    void (* const printcoordinate)(struct Coordinate*, unsigned int);

// input: pointer to struct, file data
    bool (* const getheader)      (struct Header**, const char*);

// input: pointer of pointer to struct, order, file data
// ** = 'pass by reference' of a pointer to struct
    bool (* const getmeshheader)  (struct MeshHeader**, 
                                   unsigned int i, 
                                   const char * const);

// input: pointer to struct, offset of file data batch is at, file data
    bool (* const getbatch)       (struct Batch*, 
                                   unsigned int offset, 
                                   const char * const);

// input: pointer to struct, order, file data, file size
    bool (* const getmesh)        (struct Mesh*, 
                                   unsigned int i, 
                                   const char*,
                                   unsigned int);
} fn_devil1geo;
extern fn_devil1geo const DEVIL1GEO;

#endif

